package cn.kys.modules.security.service;

import cn.kys.common.exception.BadRequestException;
import cn.kys.modules.security.security.vo.JwtUser;
import cn.kys.modules.system.service.RoleService;
import cn.kys.modules.system.service.UserService;
import cn.kys.modules.system.service.dto.DeptSmallDto;
import cn.kys.modules.system.service.dto.JobSmallDto;
import cn.kys.modules.system.service.dto.UserDto;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

/**功能描述：获取用户信息接口实现
 * @Auther:http://www.kys.cn
 * @Date:2020/3/28
 * @Description:cn.kys.modules.security.service
 * @version:1.0
 */
@Service("userDetailsService")
//如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class UserDetailsServiceImpl implements UserDetailsService {

    private final UserService userService;

    private final RoleService roleService;

    /**
     * 构造方法
     * @param userService
     * @param roleService
     */
    public UserDetailsServiceImpl(UserService userService, RoleService roleService) {
        this.userService = userService;
        this.roleService = roleService;
    }

    /**
     * 根据用户名获取用户信息
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserDto user = userService.findByName(username);
        if(user==null){
            throw new BadRequestException("账号不存在");
        }else {
            if(!user.getEnabled()){
                throw new BadRequestException("账号未激活");
            }
        }
        return createJwtUser(user);
    }

    private UserDetails createJwtUser(UserDto user) {
        return new JwtUser(
                user.getId(),
                user.getUsername(),
                user.getNickName(),
                user.getSex(),
                user.getPassword(),
                user.getAvatar(),
                user.getEmail(),
                user.getPhone(),
                Optional.ofNullable(user.getDept()).map(DeptSmallDto::getName).orElse(null),
                Optional.ofNullable(user.getJob()).map(JobSmallDto::getName).orElse(null),
                roleService.mapToGrantedAuthorities(user),
                user.getEnabled(),
                user.getCreateTime(),
                user.getLastPasswordResetTime()
        );
    }
}
